package sg.edu.nus.iss.vmcs.customer;

import java.util.Observable;
import java.util.Observer;
import sg.edu.nus.iss.vmcs.store.*;
import sg.edu.nus.iss.vmcs.util.VMCSException;

/**
 * This class represents the control object that is for handling the dispense
 * drink use case.
 *
 */
public class DispenseController implements Observer {

    private TransactionController transCtrl;
    int selection = -1;

    /**
     * This constructor creates an instance of the Dispense Controller object.It
     * receives the reference for the Transaction Controller object as a
     * parameter.
     *
     * @param tctrl Transaction Controller
     * @see TransactionController
     */
    public DispenseController(TransactionController tctrl) {
        transCtrl = tctrl;
          Store store = transCtrl.getStoreController().getStore(Store.DRINK);
            StoreItem[] storeItems = store.getItems();
            for (int i = 0; i < storeItems.length; i++) {
                storeItems[i].addObserver(this);
            }
    }

    /**
     * This operation will be used to instruct the Can Collection Box to remove
     * the drinks can shape or drink brand name from being displayed.
     */
    public void resetCan() {
        transCtrl.getCustomerPanel().getCollectCan().setValue("No CAN");
    }

    /**
     * This operation will be used to activate/deactivate (as indicated through
     * a parameter) the Drink Selection Box so that transactions can continue or
     * will be disallowed.
     *
     * @param allow boolean state (true or false)
     */
    public void allowSelection(boolean allow) {
        if (allow) {
            Store store = transCtrl.getStoreController().getStore(Store.DRINK);
            StoreItem[] storeItems = store.getItems();
            for (int i = 0; i < storeItems.length; i++) {
                storeItems[i].addObserver(this);
                if (storeItems[i].getQuantity() <= 0) {
                    transCtrl.getCustomerPanel().getDrinkInput()
                            .setItemState(i, false);
                } else {
                    transCtrl.getCustomerPanel().getDrinkInput()
                            .setItemState(i, true);
                }
            }
        } else {
            if (transCtrl.getCustomerPanel() != null) {
                transCtrl.getCustomerPanel().getDrinkInput().setActive(allow);
            }
        }
    }

    /**
     * This operation will be used to dispense a drink. It will : 1 Instruct the
     * Drinks Store to dispense the drink. It will also instruct the Can
     * Collection Box to display a can shape. 2 Instruct the Store Controller to
     * update the Drinks Store Display on the Machinery Simulator Panel. 3 In
     * case of fault detection, it will send a "fault detected" response to the
     * Transaction Controller
     *
     * @param selection Integer value
     * @return boolean state
     * @throws VMCSException Exception for dispense drinks
     */
    
    public boolean dispenseDrink(int selection) throws VMCSException {
        this.selection = selection;
        try {
            transCtrl.getMainController().getMachineryController().displayMachineryPanel();
            transCtrl.getMainController().getMachineryController().dispenseDrink(selection);
        } catch (VMCSException e) {
            transCtrl.terminateFault(this);
            throw new VMCSException("Dispense Drinks", e.getMessage());
        }
        return true;
    }

    /**
     * This operation is used to display the latest stock and price information
     * on the Drink Selection Box.
     *
     * @param selection Integer value
     */
    
    //not needed anymore, moved to Update method. (updating Drink SelectionBox)
    
//    private void updateDrinkSelection(int selection) {
//        DrinksStore drinksStore = (DrinksStore) transCtrl.getStoreController().getStore(Store.DRINK);
//        DrinksStoreItem drinksStoreItem = (DrinksStoreItem) drinksStore.getStoreItem(selection);
//        DrinksBrand drinksBrand = (DrinksBrand) drinksStoreItem.getContent();
//      
//        int qty = drinksStoreItem.getQuantity();
//        int price = drinksBrand.getPrice();
//        
//        String name = drinksBrand.getName();
//        transCtrl.getCustomerPanel().getDrinkInput().update(selection, qty, price, name);
//    }

    public void updateDrinkPanel() {
    }
    
//    @Override
//    protected void finalize() {
//        Store store = transCtrl.getStoreController().getStore(Store.DRINK);
//        StoreItem[] storeItems = store.getItems();
//        for (int i = 0; i < storeItems.length; i++) {
//            storeItems[i].deleteObserver(this);
//        }
//    }
    
    
    // Applied Observer pattern, as soon as StoreItem quantity changed, this method will be invoked.
    // update labelled display & DrinkSelectionBox
    @Override
    public void update(Observable o, Object arg) {
    
        if (o instanceof DrinksStoreItem) {
            DrinksStoreItem item = (DrinksStoreItem) o;

            DrinksBrand drinksBrand = (DrinksBrand) item.getContent();
            transCtrl.getCustomerPanel().getCollectCan().setValue(drinksBrand.getName());

            int qty = item.getQuantity();
            int price = drinksBrand.getPrice();
            String name = drinksBrand.getName();

            transCtrl.getCustomerPanel().getDrinkInput().update(selection, qty, price, name);
        }
    }
}
